
package com.jf.cloud.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import com.jf.cloud.api.order.bo.UserScoreLogOrderBO;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.api.product.feign.SpuFeignClient;
import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.database.util.PageUtil;
import com.jf.cloud.common.database.vo.PageVO;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.vo.OrderItemVO;
import com.jf.cloud.common.product.vo.SpuVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.user.mapper.UserScoreLogMapper;
import com.jf.cloud.user.model.UserScoreLog;
import com.jf.cloud.user.service.UserScoreLogService;
import com.jf.cloud.user.vo.UserScoreLogVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户积分记录
 *
 * @author zz
 * @date 2020-12-08 10:16:53
 */
@Service
public class UserScoreLogServiceImpl implements UserScoreLogService {

    @Autowired
    private UserScoreLogMapper userScoreLogMapper;
    @Autowired
    private SpuFeignClient spuFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;

    @Override
    public PageVO<UserScoreLogVO> page(PageDTO pageDTO) {
        Long userId = AuthUserContext.get().getUserId();
        return PageUtil.doPage(pageDTO, () -> userScoreLogMapper.list(userId));
    }

    @Override
    public PageVO<UserScoreLogVO> pageByIoTypeAndSource(PageDTO pageDTO, Integer ioType, Integer source) {
        Long userId = AuthUserContext.get().getUserId();
        return PageUtil.doPage(pageDTO, () -> userScoreLogMapper.listByIoTypeAndSource(userId,ioType,source));
    }

    @Override
    public PageVO<UserScoreLogVO> pageByUserId(PageDTO pageDTO, Long userId) {
        return PageUtil.doPage(pageDTO, () -> userScoreLogMapper.list(userId));
    }

    @Override
    public UserScoreLog getByLogId(Long logId) {
        return userScoreLogMapper.getByLogId(logId);
    }

    @Override
    public void save(UserScoreLog userScoreLog) {
        userScoreLogMapper.save(userScoreLog);
    }

    @Override
    public void update(UserScoreLog userScoreLog) {
        userScoreLogMapper.update(userScoreLog);
    }

    @Override
    public void deleteById(Long logId) {
        userScoreLogMapper.deleteById(logId);
    }

    @Override
    public void deleteByUserId(Long userId) {
        userScoreLogMapper.deleteByUserId(userId);
    }

    @Override
    public int saveBatch(List<UserScoreLog> userScoreLogs) {
        return userScoreLogMapper.saveBatch(userScoreLogs);
    }

    @Override
    public Integer countByUserIdAndDateTimeAndType(Integer type, Long userId, DateTime beginOfDay, DateTime endOfDay) {
        return userScoreLogMapper.countByUserIdAndDateTimeAndType(type,userId,beginOfDay,endOfDay);
    }

    @Override
    public Integer getConsecutiveDays(Long userId) {
        return userScoreLogMapper.getConsecutiveDays(userId);
    }

    @Override
    public UserScoreLog getOrderScoreLog(Long userId, Long bizId, Integer source, Integer ioType) {
        return userScoreLogMapper.getOrderScoreLog(userId,bizId,source,ioType);
    }

    @Override
    public PageVO<UserScoreLogVO> scoreProdPage(PageDTO pageDTO) {
        PageVO<UserScoreLogVO> userScoreLogPage = PageUtil.doPage(pageDTO, () -> userScoreLogMapper.listScoreLog(AuthUserContext.get().getUserId()));
        if (CollUtil.isEmpty(userScoreLogPage.getList())) {
            return userScoreLogPage;
        }
        List<Long> orderIds = userScoreLogPage.getList().stream().filter(userScoreLogVO -> Objects.nonNull(userScoreLogVO.getBizId())).map(UserScoreLogVO::getBizId).collect(Collectors.toList());
        // 获取订单信息
        ServerResponseEntity<List<OrderItemVO>> orderResponseEntity = orderFeignClient.listOrderItemByOrderIds(orderIds);
        if (orderResponseEntity.isFail()) {
            throw new LuckException(orderResponseEntity.getMsg());
        }
        //获取订单数据
        ServerResponseEntity<List<UserScoreLogOrderBO>> orderResponse = orderFeignClient.getUserScoreLogDetail(new ArrayList<>(orderIds));
        if (!Objects.equals(orderResponse.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(orderResponse.getMsg());
        }
        Map<Long, UserScoreLogOrderBO> orderScoreMap = orderResponse.getData().stream().collect(Collectors.toMap(UserScoreLogOrderBO::getOrderId, u -> u));
        Map<Long, Long> orderMap = new HashMap<>(16);
        for (OrderItemVO orderItemVO : orderResponseEntity.getData()) {
            // 积分商品只有一个订单项
            orderMap.put(orderItemVO.getOrderId(), orderItemVO.getSpuId());
        }
        ServerResponseEntity<List<SpuVO>> prodResponseEntity = spuFeignClient.listSpuBySpuIds(new ArrayList<>(orderMap.values()));
        if (prodResponseEntity.isFail()){
            throw new LuckException(prodResponseEntity.getMsg());
        }
        Map<Long, SpuVO> spuMap = prodResponseEntity.getData().stream().collect(Collectors.toMap(SpuVO::getSpuId, s->s));
        for (UserScoreLogVO userScoreLogVO : userScoreLogPage.getList()) {
            SpuVO spuVO = spuMap.get(orderMap.get(userScoreLogVO.getBizId()));
            UserScoreLogOrderBO userScoreLogOrderBO = orderScoreMap.get(userScoreLogVO.getBizId());
            if (Objects.nonNull(userScoreLogOrderBO)) {
                userScoreLogVO.setActualTotal(userScoreLogOrderBO.getActualTotal());
                userScoreLogVO.setScoreFee(userScoreLogOrderBO.getScoreFee());
                userScoreLogVO.setAllCount(userScoreLogOrderBO.getAllCount());
            }
            if (Objects.isNull(spuVO)) {
                continue;
            }
            userScoreLogVO.setSpuName(spuVO.getName());
            userScoreLogVO.setMainImgUrl(spuVO.getMainImgUrl());
            userScoreLogVO.setSingleScoreFee(spuVO.getScoreFee());
        }
        return userScoreLogPage;
    }

    @Override
    public Long getScoreCountByRefundIds(List<Long> refundIds) {
        if (CollUtil.isEmpty(refundIds)) {
            return 0L;
        }
        return userScoreLogMapper.getScoreCountByRefundIds(refundIds);
    }

    @Override
    public UserScoreLog getExpireScoreLogByUserId(Long userId) {
        return userScoreLogMapper.getExpireScoreLogByUserId(userId);
    }
}
